<template>
    <div class="a-form-item c-position-relative">
        <div class="error-message c-font-size-xs c-position-absolute" v-if="state.validator.valid === false" :style="[
            form?.myLabelWidth !== undefined
                ? `margin-left: ${form.myLabelWidth}px;`
                : '',
        ]">
            {{ state.validator.errorMessage }}
        </div>
        <div class="diff-tips c-font-size-xs c-position-absolute" :class="{ error: !state.diff.valid }">
            {{ state.diff.text }}
        </div>
        <div class="c-g-h-auto-1fr c-g-v-center">
            <a-tooltip :size="mySize" :sharp="mySharp" :tips="props.tips" v-if="props.tips">
                <a-label ref="label" class="c-position-relative" :plain="true">
                    <span v-if="props.withTipsFlag && form?.labelAlign === 'right'" class="fa fa-fw fa-question-circle-o"></span>
                    <span>{{ props.label }}</span>
                    <span v-if="props.withTipsFlag &&
                        (form?.labelAlign === 'left' ||
                            form?.labelAlign === 'center')
                        " class="fa fa-fw fa-question-circle-o"></span>
                    <div v-if="myRequired" class="required-tag c-position-absolute c-f-h c-f-center-center" :class="`c-color-${myColor}`">
                        *
                    </div>
                </a-label>
            </a-tooltip>
            <a-label ref="label" class="c-position-relative" v-else :plain="true">
                <span>{{ props.label }}</span>
                <div v-if="myRequired" class="required-tag c-position-absolute c-f-h c-f-center-center" :class="`c-color-${myColor}`">
                    *
                </div>
            </a-label>
            <slot></slot>
        </div>
    </div>
</template>

<style lang="scss" scoped>
@import "../scss/vars";

.error-message {
    color: red;
    left: 0;
    top: 100%;
    word-break: keep-all;
    user-select: none;
    pointer-events: none;
}

.diff-tips {
    color: $defaultShadowColor;
    right: 0;
    top: 100%;
    user-select: none;
    pointer-events: none;

    &.error {
        color: red;
    }
}

.required-tag {
    background-color: transparent;
    top: 0;
    right: 4px;
    user-select: none;
    pointer-events: none;
}
</style>

<script setup lang="ts">
import ATooltip from './ATooltip.vue'
import ALabel from './ALabel.vue'
import { FormBasePropsType, FormProvided, FormItemProvided } from '@/types'
import { computed, inject, provide, reactive } from 'vue'

interface PropsType extends FormBasePropsType {
    label?: string
    tips?: string
    withTipsFlag?: boolean
    required?: boolean
}
const props = withDefaults(defineProps<PropsType>(), {
    color: undefined,
    disabled: undefined,
    size: undefined,
    sharp: undefined,
    label: undefined,
    tips: undefined,
    withTipsFlag: true,
    required: undefined,
})

interface StateValidatorType {
    valid?: boolean
    errorMessage?: string
}
interface StateDiffType {
    valid?: boolean
    text?: string
}
interface StateType {
    validator: StateValidatorType
    diff: StateDiffType
    inputRequired: boolean
}
const state = reactive<StateType>({
    validator: {
        valid: undefined,
        errorMessage: undefined,
    },
    diff: {
        valid: undefined,
        text: undefined,
    },
    inputRequired: false,
})

const form = inject<FormProvided | undefined>('form', undefined)

const myColor = computed(() => {
    return props.color ?? form?.value.color ?? 'default'
})
const mySize = computed(() => {
    return props.size ?? form?.value.size ?? 'm'
})
const mySharp = computed(() => {
    return props.sharp ?? form?.value.sharp ?? false
})
const myRequired = computed(() => {
    return props.required ?? state.inputRequired
})
const methods = {
    setValidateResult(valid: boolean | undefined, errorMessage: string | undefined) {
        state.validator.valid = valid
        state.validator.errorMessage = errorMessage
    },
    setDiffResult(valid: boolean | undefined, text: string | undefined) {
        state.diff.valid = valid
        state.diff.text = text
    },
    setInputRequired(required: boolean) {
        state.inputRequired = required
    },
}
provide<FormItemProvided>('formItem', computed(() => {
    return {
        color: props.color,
        disabled: props.disabled,
        size: props.size,
        sharp: props.sharp,
        setDiffResult: methods.setDiffResult,
        setInputRequired: methods.setInputRequired,
        setValidateResult: methods.setValidateResult,
    }
}))
</script>